<?php

/**
 *
 * @author zhouming
 *
 */
class Wechat_model extends MY_Model {

	const WEIXIN_TOKEN = 'dawangfuBoss' ;

	public  $appId = 'wx5a2ba62dcf70277c' ; //AppID(应用ID)
	public $secret = '5010de0e132d6d00c2bb43793fe4ee44' ; //AppSecret(应用密钥)
	public $project = '';
	private $scope_base = 'snsapi_base' ;
	private $scope_user_info = 'snsapi_userinfo' ;
	
	public function __construct(){
		parent::__construct() ;
		$this->init();
	}
	
	public function init($config = array()){
		if(empty($config)){
			$this->config->load('wechat_config', TRUE);
			$config = $this->config->item('wechat_config');
			$config = $config['boss'];
			$this->appId = $config['appId'];
			$this->secret = $config['secret'];
			$this->project = $config['project'];
				
		}else{
			$this->appId = $config['appId'];
			$this->secret = $config['secret'];
			$this->project = $config['project'];
		}
	}

	public function valid(){
		$echoStr = $_GET["echostr"] ;
		if($this->checkSignature()){
			echo $echoStr ;
			exit ;
		}
	}

	private function checkSignature(){
		$signature = $_GET["signature"] ;
		$timestamp = $_GET["timestamp"] ;
		$nonce = $_GET["nonce"] ;

		$token = self::WEIXIN_TOKEN ;
		$tmpArr = array($token , $timestamp , $nonce) ;
		//sort($tmpArr);
		sort($tmpArr , SORT_STRING) ;
		$tmpStr = implode($tmpArr) ;
		$tmpStr = sha1($tmpStr) ;

		if($tmpStr == $signature){
			return true ;
		}else{
			return false ;
		}
	}

	/**
	 * 是否微信浏览器
	 * @return boolean
	 */
	public function is_weixin(){
		if(strpos($_SERVER['HTTP_USER_AGENT'] , 'MicroMessenger') !== false){
			return true ;
		}
		return false ;
	}

	public function getOAuthCode($type = 'base' , $state = ''){
		$current_url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ;
		$redirect_uri = urlencode($current_url) ;
		$appid = $this->appId ;
		$response_type = 'code' ;
		$scope = $this->scope_base ;
		if($type == 'userInfo'){
			$scope = $this->scope_user_info ;
		}
		$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' . $appid . '&redirect_uri=' . $redirect_uri . '&response_type=' . $response_type . '&scope=' . $scope ;
		if($state != ''){
			$url .= '&state=' . $state ;
		}
		$url.= '#wechat_redirect' ;
		echo '<script type="text/javascript">' ;
		echo 'location.href = "' . $url . '";' ;
		echo '</script>' ;
		exit ;
	}

	public function getOAuthAccessToken($code){
		$appid = $this->appId ;
		$secret = $this->secret ;
		$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid . '&secret=' . $secret . '&code=' . $code . '&grant_type=authorization_code' ;
		$resutl = array() ;
		for($i = 0 ; $i < 3 ; $i ++){
			$resutl = json_decode(file_get_contents($url)) ;
			if(property_exists($resutl , 'openid')){
				break ;
			}
		}
		return $resutl ;
	}

	public function getAccessToken(){
		$accessToken = $this->getCache() ;
		if(!$accessToken || $_GET['refreshCache']==1){
			$appid = $this->appId ;
			$secret = $this->secret ;
			$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $secret ;
			$resutl = array() ;
			for($i = 0 ; $i < 3 ; $i ++){
				$resutl = json_decode(file_get_contents($url) , true) ;
				if(isset($resutl['access_token'])){
					break ;
				}
			}
			$accessToken = $resutl['access_token'] ;
			$this->setCache($accessToken) ;
		}

		return $accessToken ;
	}

	public function setCache($accessToken){
		if($this->project == 'boss'){
		    $content = $accessToken . '&&' . date('Y-m-d H:i:s') ;
			$filename = FCPATH . 'access_token.txt' ;
			file_put_contents($filename , $content) ;
		}elseif($this->project == 'mobile'){
		    $key = Tool::getCacheKey('wechat_access_token');
		    $this->load->driver('cache' , array('adapter' => 'redis'));
		    $this->cache->redis->save($key , $accessToken , 5400);
		}
	}

	public function getCache(){
		$accessToken = '' ;
		if($this->project == 'boss'){
			$filename = FCPATH . 'access_token.txt' ;
			$content = file_get_contents($filename) ;
			$tokenArr = explode('&&' , $content) ;
			$tokenTime = strtotime($tokenArr[1]) ;
			$currentTime = time() ;
			if(($currentTime - $tokenTime) <= 5400){
			    $accessToken = $tokenArr[0] ;
			}
		}elseif($this->project == 'mobile'){
		    $key = Tool::getCacheKey('wechat_access_token');
		    $this->load->driver('cache' , array('adapter' => 'redis'));
		    $accessToken = $this->cache->redis->get($key);
		}
		return $accessToken ;
	}

	public function jsapiTicket(){
		$jsapiTicket = '' ;
		$accessToken = $this->getAccessToken() ;
		if($accessToken){
			$url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $accessToken . '&type=jsapi' ;
			$resutl = json_decode(file_get_contents($url) , true) ;
			$resutl = array() ;
			for($i = 0 ; $i < 3 ; $i ++){
				$resutl = json_decode(file_get_contents($url) , true) ;
				if(isset($resutl['ticket'])){
					break ;
				}
			}
			$jsapiTicket = $resutl['ticket'] ;
		}
		return $jsapiTicket ;
	}

	public function responseMsg(){
		$postStr = $GLOBALS["HTTP_RAW_POST_DATA"] ;
		if(!empty($postStr)){
			$postObj = simplexml_load_string($postStr , 'SimpleXMLElement' , LIBXML_NOCDATA) ;
			$RX_TYPE = trim($postObj->MsgType) ;

			switch($RX_TYPE){
				case "text":
					$resultStr = $this->receiveText($postObj) ;
					break ;
				case "event":
					$resultStr = $this->receiveEvent($postObj) ;
					break ;
				default:
					$resultStr = "" ;
					break ;
			}
			echo $resultStr ;
		}else{
			echo "" ;
			exit ;
		}
	}

	private function receiveText($object){
		$funcFlag = 0 ;
		//$title = $GLOBALS['db']->query_value("select title from news where id = 1");
		$title = "大旺福" ;
		$contentStr = "你发送的内容为：" . $object->Content . "&&&" . $title ;
		//$contentStr = "你发送的内容为：".$object->Content."&&&".$title."&&&".$object->FromUserName."&&&".$object->ToUserName;
		$resultStr = $this->transmitText($object , $contentStr , $funcFlag) ;
		return $resultStr ;
	}

	private function receiveEvent($object){
		$contentStr = "" ;
		switch($object->Event){
			case "subscribe":

				$wx_open_id = $object->FromUserName ;
				if(property_exists($object , 'EventKey') && $object->EventKey != ''){
					//$contentStr = $object->EventKey . '&&1111' ;
				}else{
					//$contentStr = "欢迎关注大旺福网上超市商家公众号，首次使用请绑定商家账户。<a href=\"http://b.dawangfu.com/wechat/login?&wx_open_id=" . $wx_open_id . "\">立即绑定</a>" ;
				}

			case "unsubscribe":
				//$contentStr = 'haokexi';
				break ;
			case "CLICK":
				switch($object->EventKey){
					
				}
				break ;
			default:
				$contentStr = $object->Event ;
				break ;
		}
		if(is_array($contentStr)){
			$resultStr = $this->transmitNews($object , $contentStr) ;
		}else{
			$resultStr = $this->transmitText($object , $contentStr) ;
		}
		return $resultStr ;
	}

	private function transmitText($object , $content , $funcFlag = 0){
		$textTpl = "<xml>
                <ToUserName><![CDATA[%s]]></ToUserName>
                <FromUserName><![CDATA[%s]]></FromUserName>
                <CreateTime>%s</CreateTime>
                <MsgType><![CDATA[text]]></MsgType>
                <Content><![CDATA[%s]]></Content>
                <FuncFlag>%d</FuncFlag>
                </xml>" ;
		$resultStr = sprintf($textTpl , $object->FromUserName , $object->ToUserName , time() , $content , $funcFlag) ;
		return $resultStr ;
	}

	private function transmitNews($object , $arr_item , $funcFlag = 0){
		//首条标题28字，其他标题39字
		if(!is_array($arr_item))
			return ;

		$itemTpl = "<item>
                        <Title><![CDATA[%s]]></Title>
                        <Description><![CDATA[%s]]></Description>
                        <PicUrl><![CDATA[%s]]></PicUrl>
                        <Url><![CDATA[%s]]></Url>
                    </item>" ;
		$item_str = "" ;
		foreach($arr_item as $item)
			$item_str .= sprintf($itemTpl , $item['Title'] , $item['Description'] , $item['PicUrl'] , $item['Url']) ;

		$newsTpl = "<xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[news]]></MsgType>
            <ArticleCount>%s</ArticleCount>
            <Articles>$item_str</Articles>
            </xml>" ;

		$resultStr = sprintf($newsTpl , $object->FromUserName , $object->ToUserName , time() , count($arr_item)) ;
		return $resultStr ;
	}

	public function httpRequest($url , $data = array() , $method = 'get'){
		$result = array() ;
		if($method == 'post' && !empty($data)){
			$result = $this->_post($url , $data) ;
		}else{
			$result = $this->_get($url , $data) ;
		}
		return $result ;
	}

	private function _get($url , $data){
		$output = array() ;
		if(!empty($data)){
			$url .= '?' . http_build_query($data , 'dawangfu_') ;
		}
		$ch = curl_init() ;
		curl_setopt($ch , CURLOPT_URL , $url) ;
		curl_setopt($ch , CURLOPT_RETURNTRANSFER , 1) ;
		curl_setopt($ch , CURLOPT_SSL_VERIFYPEER , FALSE) ;
		curl_setopt($ch , CURLOPT_SSL_VERIFYHOST , FALSE) ;
		$output = curl_exec($ch) ;
		curl_close($ch) ;
		return $output ;
	}

	private function _post($url , $data){
		$output = array() ;
		$ch = curl_init() ;
		curl_setopt($ch , CURLOPT_URL , $url) ;
		curl_setopt($ch , CURLOPT_SSL_VERIFYPEER , FALSE) ;
		curl_setopt($ch , CURLOPT_SSL_VERIFYHOST , FALSE) ;
		if(!empty($data)){
			curl_setopt($ch , CURLOPT_POST , 1) ;
			curl_setopt($ch , CURLOPT_POSTFIELDS , $data) ;
		}
		curl_setopt($ch , CURLOPT_RETURNTRANSFER , 1) ;
		$output = curl_exec($ch) ;
		curl_close($ch) ;
		return $output ;
	}
	/**
	 * 发送账户余额变动通知
	 */
	public function sendCountChangeMessage($openId , $changedCount , $total ,$remark){
		$message = $this->buildCountChangeTemplate($openId , $changedCount , $total,$remark);
		$message = urldecode(json_encode($message));
		$result = $this->sendTemplateMessage($message);
		return $result;
	}
	/**
	 * 生成账户变动模板消息
	 * @param unknown $type
	 * @param unknown $openId
	 * @param array $baseData
	 */
	public function buildCountChangeTemplate($openId , $changedCount , $total ,$remark ){
		$template = array();
		$template['touser'] = $openId;
		$template['template_id'] = 'h52o9uGiQjm6EDJSSmTls7pinTz9tfzub6hs7w9FcyA';
		$template['url'] = 'http://wq.dawangfu.com/member/balance/';
		$template['data'] = array(
				'first'=>array('value'=>'尊敬的用户，您的账户余额发生变化','color'=>'#173177'),
				'keyword1'=>array('value'=>$changedCount,'color'=>'#FF0000'),
				'keyword2'=>array('value'=>$total,'color'=>'#173177'),
				'remark'=>array('value'=>$remark,'color'=>'#FF0000')
		);
		return $template;
	}
	
	public function sendPayNotifyMessage($openId,$orderNum,$orderTime,$totalFee,$needPay,$remark){
	    $template = array();
	    $template['touser'] = $openId;
	    $template['template_id'] = 'qDSUNXMyrpz2_eRbTS63bnVn28V4bwqAfEMFp5G4C3I';
	    $template['url'] = 'http://wq.dawangfu.com/member/orderDetail/' . $orderNum;;
	    $template['data'] = array(
	        'first'=>array('value'=>'尊敬的用户，您的订单:' . $orderNum . '还需支付'  . $needPay . "元，请尽快完成支付，超过15分钟未支付，系统将取消该订单！",'color'=>'#173177'),
	        'keyword1'=>array('value'=>$orderNum,'color'=>'#FF0000'),
	        'keyword2'=>array('value'=>$totalFee,'color'=>'#173177'),
	        'keyword3'=>array('value'=>'待付款','color'=>'#173177'),
	        'remark'=>array('value'=>$remark,'color'=>'#FF0000')
	    );
	    $message = urldecode(json_encode($template));
	    $result = $this->sendTemplateMessage($message);
	    return $result;
	}
	/**
	 *  发送模板消息
	 * @param unknown $data
	 * @return mixed
	 */
	public function sendTemplateMessage($data){
		$accessToken = $this->getAccessToken();
		$url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . $accessToken;
		$result = $this->httpRequest($url,$data,'post');
		return json_decode($result,true);
	}
}
